小智雅汇 2018-12-27 16:40
Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外,它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application),所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是Microsoft Windows 32位平台的应用程序编程接口。
我们对待API函数不必刻意去研究每一个函数的用法,那也是不现实的(能用得到的API函数有几千个呢)。正如某位大虾所说:API不要去学,在需要的时候去查API帮助就足够了。但是,许多API函数令人难以理解,易于误用,还会导致出错,这一切都阻碍了它的推广。
应用程序接口经常是软件开发工具包 (SDK)的一部分。
1 Windows数据类型及与标准C数据类型的关系
查看 Windows 数据类型的定义可以看到,所有的 Windows 数据类型都是由 C 数据类型经过类型重定义得到的。如 DWORD 实质上就是 unsigned long 数据类型,32 位的无符号整型。而在 Windows 程序设计中经常用到的 HANDLE 类型实质上是无类型指针 void。所有的 Windows 数据类型都是通过这种方式在 SDK 的头文件中进行定义的,它们都是来源于标准 C 的数据类型。实际上 VC 编译器是一个完整的 C 编译器,此外并没有过多的扩展。Windows 数据类型也不是 VC 的内建类型,而是从标准 C 类型重定义得到。
Windows API 函数、数据结构等都是采用 Windows 数据类型。比如 Windows API 函数的入口参数、返回值等都是 Windows 数据类型。因此学习 Windows API 程序设计必须要了解Windows 数据类型。
事实上,这些 Windows 数据类型都是从标准 C 的数据类型通过typedef运算符经过类型重定义而来。Windows 数据类型的命名都很有规律。一个类型不再分成几个英文字,而是写成一个缩写的、大小的英文单字(指针符号也用P来表示)。比如,
typedef const TCHAR* LPCTSTR;
typedef unsigned long DWORD
COLORREF也是一种unsigned long类型,如0xFFFFFFFF,RGB(255,255,255)
typedef unsigned short * BSTR;
typedef unsigned char BYTE;
typedef char* LPSTR;
typedef unsigned short WORD;
所有的无符号变量都加上U来区分。如:
typedef unsigned int UINT;
所有的指针类型变量都加上P来区分。如:
typedef BYTE near * PBYTE;
typedef BYTE far* LPBYTE;
typedef int near* PINT;
typedef int far * LPINT;
typedef WORD near * PWORD;
typedef WORD far* LPWORD;
typedef DWORD near * PDWORD;
typedef DWORD far * LPDWORD;
typedef void far* LPVOID;
typedef CONST void far * LPCVOID;
//near和far是c语言相对古老的的用法,用于声明变量在内存中的远近。
所有的常量指针都使用C。如:
typedef CONST void* LPCVOID;
typedef CONST *CHAR LPCSTR;
2 Windows中的字符串指针类型
很早以前,各国文字都有自己的编码方式,而且每个国家字符的字节也不一样(多字节字符)。后来,拥有了统一的编码方式,统一了编码Unicode。
vs中创建项目时,默认是Unicode编码的。可以使用wchar_t来声明Unicode编码的字符串,而且字符串声明时在前面加上L。TCHAR是一个怪胎,他是char和wchar_t的自适应版。
const char * p = “aaa”; //内存中,每个a占有一个字节
const char * pc = “中国”;//内存中,每个汉字占有两个字节
const wchar_t * pU = L”aa”;//内存中,每个a占有两个字节
const wchar_t * pcU = L”中国”;//内存中,每个汉字占有一个字节
const TCHAR * s = L”aa”;//这个TCHAR声明时,必须声明成Unicode编码的串
//修改vs的编码方式为’多字节字符集’后
const TCHAR * s =L”aa”;//这就会报错,因为这时候TCHAR是char类型
const TCHAR * s =”aa”;//不会报错
3 Windows中的句柄类型
句柄类型是Windows API中一种特殊的数据类型。
各种句柄类型的命令方式一般都是在对象名前加“H”。Windows 系统中有很多对象,所有表示一个对象的数据类型都是句柄,每一种对象都对应着一种句柄类型,比如与位图 ( BITMAP)对应的句柄类型为“HBITMAP”,与菜单(MENU)对应的句柄类型为“HMENU”,与窗口(WINDOW)对应的句柄类型为“HWND”。
HWND 窗口句柄
HINSTANCE 进程实例句柄
HCURSOR 光标句柄
HICON 图标句柄
HMENU 菜单句柄
HFONT 字体句柄
HFILE 文件句柄
在API中,资源对象用数据体来表示。通用句柄HANDLE有时候是逻辑指针,大多数时候是结构体指针,特殊句柄如HMENU等是结构体指针。
4 Windows中的数据结构
Windows 中包含很多种数据结构类型,在不同类型的 API 中会使用到不同的数据结构,数据结构的数量众多,这些数据结构通常会作为一些 API 的参数输入。Windows API 中的数据结构定义具有一定的特点,一般情况下,Windows 系统中使用全大写来命名结构体、共用体,并使用“_”来分隔单词,在结构名加“LP”或“P”表示指向数据结构的指针。
结构体类型,如POINT、SIZE、RECT。
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT, * PPOINT, * LPPOINT;//结构体别名
typedef struct tagSIZE
{
LONGcx;
LONGcy;
} SIZE, * PSIZE, * LPSIZE;
typedef struct tagRECT
{
LONGleft;
LONGtop;
LONGright;
LONGbottom;
} RECT, * PRECT, * LPRECT;
5 Windows数据类型与Windows API
Windows API 函数的参数、返回值或一些重要的常量使用的数据类型都是 Windows 数据类型。MessageBox 函数的返回值是 int 型的,是标准 C 数据类型,但是所有的参数都使用了Windows 数据类型。如 HWND 是一种 Windows 数据类型,用于表示窗口的句柄;LPCTSTR 也是Windows 数据类型,表示字符串常量;UINT 也是 Windows 数据类型,为无符号整型。
6 MFC中可以使用的数据类型
程序员想编写具有Windows风格的软件,必须借助API,API也因此被赋予至高无上的地位。但是,如若没有合适的Windows编程平台,那么Windows开发是一项很复杂的工作。在可视化编程IDE出来之前,那时的WINDOWS程序开发还是比较复杂的工作,程序员必须熟记一大堆常用的API函数,而且还得对WINDOWS操作系统有深入的了解。然而随着软件技术的不断发展,在WINDOWS平台上出现了很多优秀的可视化编程环境,程序员可以采用“所见即所得”的编程方式来开发具有精美用户界面和功能强大的应用程序。
这些优秀可视化编程环境操作简单、界面友好(诸如VB、VC++、DELPHI等),在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能,事实上这些类库和控件都是构架在WIN32 API函数基础之上的,是封装了的API函数的集合。它们把常用的API函数的组合在一起成为一个控件或类库,并赋予其方便的使用方法,所以极大的加速了WINDOWS应用程序开发的过程。有了这些控件和类库,程序员便可以把主要精力放在程序整体功能的设计上,而不必过于关注技术细节。
MFC以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。
实际上如果我们要开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数,虽然类库和控件使应用程序的开发简单的多,但它们只提供WINDOWS的一般功能,对于比较复杂和特殊的功能来说,使用类库和控件是非常难以实现的,这时就需要采用API函数来实现。
MFC通常包含stdafx.h头文件来提供MFC类库支持。
MFC中使用windows API数据类型要包含windows.h头文件。
在MFC中,增加了处理字符串的CString类,在编辑框框中就可以定义CString类型控件变量。
我们知道,C++的string类可以通过c_str()将其转换为char *或CString。
类似的,CString也提供了一个成员函数.GetBuffer(0),将其转换为char *或string类型。
CString 与LPCTSTR,也可以方便地进行转换:
CString cStr;
const char *lpctstr1=(LPCTSTR)cStr;
LPCTSTR lpctstr2;
CString cStr=lpctstr2;
-End-
本页共93段,4303个字符,8714 Byte(字节)